/* +------------------------------------------------------------------------+
   |                     Mobile Robot Programming Toolkit (MRPT)            |
   |                          https://www.mrpt.org/                         |
   |                                                                        |
   | Copyright (c) 2005-2019, Individual contributors, see AUTHORS file     |
   | See: https://www.mrpt.org/Authors - All rights reserved.               |
   | Released under BSD License. See: https://www.mrpt.org/License          |
   +------------------------------------------------------------------------+ */
#ifndef XSCOPY_H
#define XSCOPY_H

#define XSLISTCOPY(C)    \
	if (copy == thisPtr) \
	{                    \
		return;          \
	}                    \
	C##_assign(copy, thisPtr->m_size, thisPtr->m_data);

#define XSLISTSWAP3(C, B, S)                                             \
	if ((!a->m_data || (a->m_flags & XSDF_Managed)) &&                   \
		(!b->m_data || (b->m_flags & XSDF_Managed)))                     \
	{                                                                    \
		B tmp;                                                           \
		*((C**)&tmp.m_data) = a->m_data;                                 \
		*((XsSize*)&tmp.m_size) = a->m_size;                             \
		*((int*)&tmp.m_flags) = a->m_flags;                              \
		*((C**)&a->m_data) = b->m_data;                                  \
		*((XsSize*)&a->m_size) = b->m_size;                              \
		*((int*)&a->m_flags) = b->m_flags;                               \
		*((C**)&b->m_data) = tmp.m_data;                                 \
		*((XsSize*)&b->m_size) = tmp.m_size;                             \
		*((int*)&b->m_flags) = tmp.m_flags;                              \
	}                                                                    \
	else                                                                 \
	{ /* elementwise swap */                                             \
		XsSize i;                                                        \
		assert(a->m_size == b->m_size);                                  \
		for (i = 0; i < a->m_size; ++i) S(&a->m_data[i], &b->m_data[i]); \
	}

#define XSLISTSWAP2(C, B) XSLISTSWAP3(C, B, C##_swap)

#define XSLISTSWAP(C) XSLISTSWAP2(C, C##List)

#endif  // file guard
